package com.meichis.mcsappframework.http.download;

import com.meichis.mcsappframework.http.CallException;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * Created by jsrgc on 2017/5/31.
 */

public class DownManager {
    private static DownManager sInstance;

    private final static int CONNECT_TIMEOUT = 20;

    private static Retrofit retrofit;

    private static DownApi downApi;

    private Map<String, DownSubscriber> downMap = new ConcurrentHashMap<>();

    private DownManager() {
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
                .build();

        retrofit = new Retrofit.Builder()
                //只做校验，不请求这个地址 ，请求DownApi中Url
                .baseUrl("https://www.baidu.com/")
                .client(client)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
        downApi = retrofit.create(DownApi.class);
    }

    public static synchronized DownManager getInstance() {
        if (sInstance == null) {
            sInstance = new DownManager();
        }
        return sInstance;
    }

    public void download(String url, String destFileDir, String destFileName, DownLoadCallBack callBack) {
        DownSubscriber subscriber = new DownSubscriber<ResponseBody>(url, destFileDir, destFileName, callBack);
        downApi.downloadFile(url)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .retry(3)
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends ResponseBody>>() {
                    @Override
                    public ObservableSource<? extends ResponseBody> apply(Throwable throwable) throws Exception {
                        return Observable.error(CallException.handleException(throwable));
                    }
                })
                .subscribe(subscriber);
        downMap.put(url, subscriber);
    }

    public void cancel(String url) {
        if (downMap.containsKey(url)) {
            if (!downMap.get(url).getD().isDisposed())
                downMap.get(url).getD().dispose();
            downMap.remove(url);
        }
    }

    public void remove(String url) {
        downMap.remove(url);
    }

    public boolean isDown(String url) {
        return downMap.containsKey(url);
    }
}
